#include "app.h"
#include "sensor_service.h"
#include "stm32l0xx_nucleo.h"
#include "stm32_bluenrg_ble.h"
#include "x_nucleo_iks01a1.h"
#include "app_3axis_output.h"
#include "app_ble_irq_handle.h"
#include "app_ip.h"
#include "eeprom.h"
/*private variable************************************************************************/
extern I2C_HandleTypeDef I2C_EXPBD_Handle;
/*lis2dh12*/
extern RTC_HandleTypeDef RTCHandle;
extern volatile uint8_t random_num;
extern volatile uint8_t ble_init_flag ;
uint32_t record_pointer = 0;
extern volatile axis_type_t axis_buf[AXIS_BUFFER_SIZE];
/*low power*/
/*private function************************************************************************/

uint32_t get_eeprom_data_write_address_from_BKP(void)
{
    return HAL_RTCEx_BKUPRead(&RTCHandle, tail_address_bkp_reg);
}

void set_eeprom_data_write_address_to_BKP(uint32_t data)
{
    HAL_RTCEx_BKUPWrite(&RTCHandle, tail_address_bkp_reg, data);
}

static void eeprom_clear(void)
{
     uint32_t word_len = 0;
     
     word_len = (EEPROM_DATA_SIZE + 36)/ 4;
     eeprom_erase(word_len, EEPROM_3AXIS_CONFIG_ADDR);
 
     record_pointer = 0;
}

#if 0
static void eeprom_clear_record_cache(void)
{
     uint32_t word_len = 0;
 
     word_len = EEPROM_DATA_RECORD_SIZE *  APP_SNESOR_RECORD_WORD_LEN;
     eeprom_erase(word_len, EEPROM_DATA_BEGIN_ADDR);
}
#endif

/*eeprom data block init*/
void eeprom_data_block_init(void)
{
     eeprom_clear();
}

static void record_cache_advance_record_pointer(void)
{
    record_pointer = (record_pointer + 1) % EEPROM_DATA_RECORD_SIZE;
}

static uint32_t record_cache_get_record_pointer(void)
{
    return record_pointer;
}

static uint32_t record_cache_get_record_index(void)
{
    return (EEPROM_DATA_BEGIN_ADDR + (record_cache_get_record_pointer() * (APP_SNESOR_RECORD_WORD_LEN * 4)));
}


static void record_cache_write_record_data(uint32_t* data, uint32_t address)
{
    eeprom_data_t eeprom_data;
 
    eeprom_erase(APP_SNESOR_RECORD_WORD_LEN, address);
 
    eeprom_data.address = address;
    eeprom_data.len = APP_SNESOR_RECORD_WORD_LEN;
    eeprom_data.eeprom_data = (uint32_t*)data;
 
    eeprom_write(eeprom_data);
 
    record_cache_advance_record_pointer();
}

void app_record_cache_store(void* data)
{
    uint32_t record_write_address = 0;
				
    record_write_address = record_cache_get_record_index();
 
    record_cache_write_record_data((uint32_t*)data, record_write_address);
 
}

/**
 * @brief  EXTI line detection callback.
 * @param  Specifies the pins connected EXTI line
 * @retval None
 */

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    switch (GPIO_Pin){
     case BNRG_SPI_IRQ_PIN:
         if(ble_init_flag == 0x00)
             HCI_Isr();
         else
             app_ble_irq_callback();
     break;
     case LIS2DH12_INT1_PIN:
          
//          BSP_LED_On(LED5);
          if(LIS2DH12_X_Y_Z_Get_Axes_Raw() != 0x00)
              app_fault_handle(APP_READ_DMA_ISSUE_EEROR);
     break;
        
     default:
     break;
    }
}

void app_update_char_value_cb(uint8_t status)
{
    app_ip_update_value_callback(status);
}

#if 0
uint32_t i2c_state = 0;
static void i2c_state_test(void)
{
    eeprom_data_t eeprom_data;
    i2c_state = I2C_EXPBD_Handle.Instance->ISR;

    eeprom_erase(1, EEPROM_VOLTAGE_ADDR);
 
    eeprom_data.len = 1;
    eeprom_data.address = EEPROM_VOLTAGE_ADDR;
    eeprom_data.eeprom_data = &i2c_state;
 
    eeprom_write(eeprom_data);


}
#endif

void app_i2c_dma_rx_cmp_callback(uint8_t* data)
{
    static uint16_t count = 0, axis_flag  = 0;
//    BSP_LED_Off(LED5);
    app_dma_flag_set(DMA_BEGIN);
    if(axis_flag > AXIS_BUFFER_SIZE){
        app_fault_handle(APP_3AXIS_BUFFER_OVER);
    }
    for(count = 0; count < LIS2DH12_SAMPLE_NUMBER; count++){
     
        axis_buf[count+axis_flag].axis_x = ((int16_t)(data[(count * 6)+0] | ((data[(count * 6)+1] & 0x00FF) << 8))) / 16;
        axis_buf[count+axis_flag].axis_y = ((int16_t)(data[(count * 6)+2] | ((data[(count * 6)+3] & 0x00FF) << 8))) / 16;
        axis_buf[count+axis_flag].axis_z = ((int16_t)(data[(count * 6)+4] | ((data[(count * 6)+5] & 0x00FF) << 8))) / 16;
     
        random_num+=axis_buf[count+axis_flag].axis_x ;
    }
    
    axis_flag += LIS2DH12_SAMPLE_NUMBER;
    if(lis2dh12_sample_end_flag(axis_flag)){    
        axis_flag = 0;
        app_3axis_int_callback();
    }
    
}



